package com.example.demo.mcp.webserver;

import io.modelcontextprotocol.spec.McpSchema;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.mcp.McpToolUtils;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author zwg
 * @date 2025/9/24 21:07
 */
@Slf4j
@Service
public class WeatherService {
    private final RestClient restClient;

    public WeatherService() {
        this.restClient = RestClient.create();
    }

    /**
     * The response format from the Open-Meteo API
     */
    public record WeatherResponse(Current current) {
        public record Current(LocalDateTime time, int interval, double temperature_2m) {
        }
    }

    @Tool(description = "根据提供的城市获取天气情况")
    public String getWeather(@ToolParam(description = "The city name") String cityName,
                              @ToolParam(description = "The city code") String cityCode,
                              ToolContext toolContext) {
        log.info("getWeather: cityName={}, cityCode={}", cityName, cityCode);

        return "城市：" + cityName +
                " " + cityCode +
                " " + "今天（10 月 30 日）天气为多云，最低温度 ℃，最高温度 15℃，空气质量优，pm2.5 指数 37，湿度 33%，南风 1 级。";
    }

    //@Tool(description = "Get the temperature (in celsius) for a specific location")
    public String getTemperature(@ToolParam(description = "The location latitude") double latitude,
                                 @ToolParam(description = "The location longitude") double longitude,
                                 ToolContext toolContext) {

        log.info("getTemperature: latitude={}, longitude={}", latitude, longitude);

        /*WeatherResponse weatherResponse = restClient
                .get()
                .uri("https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m",
                        latitude, longitude)
                .retrieve()
                .body(WeatherResponse.class);

        log.info("weatherResponse: {}", weatherResponse);*/

        String responseWithPoems = "承德今天（10 月 30 日）天气为多云，最低温度 - 1℃，最高温度 15℃，空气质量优，pm2.5 指数 37，湿度 33%，南风 1 级。";//callMcpSampling(toolContext, weatherResponse);

        log.info("responseWithPoems: {}", responseWithPoems);

        return responseWithPoems;
    }

    public String callMcpSampling(ToolContext toolContext, WeatherResponse weatherResponse) {

        StringBuilder openAiWeatherPoem = new StringBuilder();
        StringBuilder anthropicWeatherPoem = new StringBuilder();

        McpToolUtils.getMcpExchange(toolContext)
                .ifPresent(exchange -> {

                    exchange.loggingNotification(McpSchema.LoggingMessageNotification.builder()
                            .level(McpSchema.LoggingLevel.INFO)
                            .data("Start sampling")
                            .build());

                    if (exchange.getClientCapabilities().sampling() != null) {
                        var messageRequestBuilder = McpSchema.CreateMessageRequest.builder()
                                .systemPrompt("You are a poet!")
                                .messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
                                        new McpSchema.TextContent(
                                                "Please write a poem about this weather forecast (temperature is in Celsius). Use markdown format :\n "
                                                        + ModelOptionsUtils
                                                        .toJsonStringPrettyPrinter(weatherResponse)))));

                        var opeAiLlmMessageRequest = messageRequestBuilder
                                .modelPreferences(McpSchema.ModelPreferences.builder().addHint("openai").build())
                                .build();
                        McpSchema.CreateMessageResult openAiLlmResponse = exchange.createMessage(opeAiLlmMessageRequest);

                        openAiWeatherPoem.append(((McpSchema.TextContent) openAiLlmResponse.content()).text());

                        var anthropicLlmMessageRequest = messageRequestBuilder
                                .modelPreferences(McpSchema.ModelPreferences.builder().addHint("anthropic").build())
                                .build();
                        McpSchema.CreateMessageResult anthropicAiLlmResponse = exchange.createMessage(anthropicLlmMessageRequest);

                        anthropicWeatherPoem.append(((McpSchema.TextContent) anthropicAiLlmResponse.content()).text());

                    }

                    exchange.loggingNotification(McpSchema.LoggingMessageNotification.builder()
                            .level(McpSchema.LoggingLevel.INFO)
                            .data("Finish Sampling")
                            .build());

                });

        String responseWithPoems = "OpenAI poem about the weather: " + openAiWeatherPoem + "\n\n" +
                "Anthropic poem about the weather: " + anthropicWeatherPoem + "\n"
                + ModelOptionsUtils.toJsonStringPrettyPrinter(weatherResponse);

        return responseWithPoems;

    }
}
